/*
 * Copyright (C) 2015 truth
 *
 * This program is non-free software, but you can redistribute it and/or modify
 * it if you are in hjj(Huangshi Hejianjiao) team.
 */
package com.truthbean.jutils.dao.impl.apache;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.truthbean.jutils.dao.apache.BaseDao;
import com.truthbean.jutils.dao.utils.DBContext;
import com.truthbean.jutils.utils.ReflectionUtils;
import com.truthbean.jutils.utils.StringUtil;

/**
 * @param <T>
 * @since Jan 15, 2015 11:20:28 AM
 * @author TruthBean
 */
public class BaseDaoImpl<T> implements BaseDao<T> {

    private final QueryRunner qr = new QueryRunner();
    private final Class<T> clazz;

    public BaseDaoImpl() {
        //反射机制
        clazz = ReflectionUtils.getSuperGenericType(getClass());
    }

    @Override
    public int update(String sql, Object... args) {
        Connection con = DBContext.getInstance().get();
        int result = 0;
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                result = qr.update(con, sql, args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "the org.apache.commons.dbutils.QueryRunner."
                                + "update(Connection, String, Object...)"
                                + "", e);
            }
        }
        return result;
    }

    @Override
    public T query(String sql, Object... args) {
        Connection con = DBContext.getInstance().get();
        T result = null;
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                result = qr.query(con, sql, new BeanHandler<T>(clazz), args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "org.apache.commons.dbutils.QueryRunner."
                                + "query(Connection, String, ResultSetHandler<T>, Object...)"
                                + "", e);
            }
        }
        return result;
    }

    @Override
    public List<T> queryForList(String sql, Object... args) {
        Connection con = DBContext.getInstance().get();
        List<T> result = null;
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                result = qr.query(con, sql, new BeanListHandler<T>(clazz), args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "org.apache.commons.dbutils.QueryRunner."
                                + "query(Connection, String, ResultSetHandler<List<T>>, Object...)"
                                + "", e);
            }
        }
        return result;
    }

    @Override
    public <V> V getSingleVal(String sql, Object... args) {
        Connection con = DBContext.getInstance().get();
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                return qr.query(con, sql, new ScalarHandler<V>(), args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "org.apache.commons.dbutils.QueryRunner."
                                + "query(Connection, String, ResultSetHandler<V>, Object...)"
                                + "", e);
            }
        }
        return null;
    }

    @Override
    public Map<String, ?> getValForMap(String sql, Object... args) {
        Connection con = DBContext.getInstance().get();
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                return qr.query(con, sql, new MapHandler(), args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "org.apache.commons.dbutils.QueryRunner."
                                + "query(Connection, String, ResultSetHandler<Map<String, Object>>, Object...)"
                                + "", e);
            }
        }
        return null;
    }

    @Override
    public <V> Set<V> getValForSet(String sql, Object... args) {
        throw new UnsupportedOperationException("this is not written");
    }

    @Override
    public int[] batch(String sql, Object[][] args) {
        Connection con = DBContext.getInstance().get();
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                return qr.batch(con, sql, args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "org.apache.commons.dbutils.QueryRunner."
                                + "batch(Connection, String, Object[][])"
                                + "", e);
            }
        }
        return null;
    }

    @Override
    public <V> List<V> getValForList(String sql, Object... args) {
        Connection con = DBContext.getInstance().get();
        if (con != null && StringUtil.isNotEmpty(sql)) {
            try {
                return qr.query(con, sql, new ColumnListHandler<V>(), args);
            } catch (SQLException e) {
                Logger.getLogger(BaseDaoImpl.class.getName()).
                        log(Level.SEVERE, "org.apache.commons.dbutils.QueryRunner."
                                + "query(Connection, String, ResultSetHandler<List<T>>, Object...)"
                                + "", e);
            }
        }
        return null;
    }

}
